package ga;
import ga.chromosome.Chromosome;
import ga.chromosome.Population;
import ga.fitness.FitnessCalc;
import ga.gene.Input;
import ga.gene.TheException;

import java.util.ArrayList;


/**
 * The Class Driver.
 */
public class Driver {

	/**
	 * The main method.
	 *
	 * @param args the arguments
	 * @throws TheException 
	 */
	public static void main(String[] args) throws TheException {
		run(50000);
//		ArrayList<Input> inputs = new ArrayList<Input>();
//		inputs.add(null);
//		inputs.add(1, new Input(1));
//		inputs.add(2, new Input(2));
//		inputs.add(3, new Input(3));
//		Chromosome temp = new Chromosome(inputs);
//		System.out.println(temp);
//		System.out.println(temp.solveSwitch());
		
//		ArrayList<Input> inputs = new ArrayList<Input>();
//		ArrayList<Boolean> outputs = new ArrayList<Boolean>();
//		/*for(int i = 1; i < Chromosome.getDefaultGenes() + Chromosome.getDefaultInputs() +1; i++)
//			inputs.add(new Input(i));*/
//		outputs.add(true);
//		outputs.add(false);
//		outputs.add(true);
//		outputs.add(false);
//		
//		outputs.add(true);
//		outputs.add(false);
//		outputs.add(true);
//		outputs.add(true);
//		FitnessCalc.setSolution(outputs);
//		inputs.add(null);
//		inputs.add(1, new Input(1, true));
//		inputs.add(2, new Input(2, false));
//		inputs.add(3, new Input(3, false));
//
//		try {
//			Chromosome temp = new Chromosome(inputs);
//			Chromosome temp2 = new Chromosome(inputs);
//			Population testPop = new Population(inputs, 5);
//			System.out.println(temp);
//			
////			System.out.println(temp2);
////			System.out.println(testPop);
////			System.out.println(testPop.toBool());
//			ArrayList<ArrayList<Boolean>> test = temp.solve();
//			ArrayList<ArrayList<Boolean>> test2 = temp.solve();
//			System.out.println(test);
//			System.out.println(test2);
////			System.out.println(temp.toBool());
////			FitnessCalc.getFitness(temp);
//		} catch (TheException e) {
//			System.out.println(e.getMessage());
//		}
		
	}
	
	/**
	 * Runs the program a certain number of times.
	 *
	 * @param numTimes the num times
	 */
	public static void run(int numTimes){
		ArrayList<Input> inputs = new ArrayList<Input>();
		inputs.add(null);
		inputs.add(1, new Input(1));
		inputs.add(2, new Input(2));
		inputs.add(3, new Input(3));
		inputs.add(3, new Input(4));
		
		ArrayList<Boolean> outputs = new ArrayList<Boolean>();
		outputs.add(true);
		outputs.add(false);
		outputs.add(true);
		outputs.add(true);
		
		outputs.add(true);
		outputs.add(false);
		outputs.add(false);
		outputs.add(true);
		
		outputs.add(true);
		outputs.add(false);
		outputs.add(true);
		outputs.add(true);
		
		outputs.add(true);
		outputs.add(false);
		outputs.add(false);
		outputs.add(true);
		
	
		FitnessCalc.setSolution(outputs);
		Population testPop;
		try {
			testPop = new Population(inputs, 10000);
			int generationCount = 0;
			int oldFitness = 100;
			int counter = 0;
			while (generationCount < numTimes){
				generationCount++;
				if(generationCount % 25 == 0)
					System.out.println(generationCount);
				testPop = Algorithm.evolvePopulation(testPop);
				if(oldFitness != testPop.getFittest().getFitness()){
					System.out.println("New Fitness! = " +testPop.getFittest().getFitness());
					testPop.getFittest().solve();
					System.out.println(testPop.getFittest().answer);
				}
				if(testPop.getFittest().getFitness() == oldFitness && oldFitness != 100){
					counter++;
					//Adjust the 100 below to change how long the program will look for a new fitness
					if(counter == 100){
						break;
					}
				}
				else{
					counter = 0;
					oldFitness = testPop.getFittest().getFitness();
				}
				
				//Adjust the 10 below to change how often the program changes its size
				if(generationCount % 30 == 0 && testPop.getFittest().getFitness() == 100){
					int row = Chromosome.getRows();
					if(row++ > 4){
						Chromosome.setLayers(Chromosome.getLayers() + 1);
						Chromosome.setRows(1);
					}
					else
						Chromosome.setRows(row);
					testPop = new Population(inputs, 10000);
				}
				
			}
			System.out.println(testPop.getFittest());
			System.out.println("Correct output is : " +testPop.getFittest().getCorrectOutput());
			
			System.out.println(testPop.getFittest().answer);
			System.out.println("Sought:" + FitnessCalc.getSolution());
			
			Chromosome test = testPop.getFittest();
			System.out.println(test.toBool());
			System.out.println(testPop.getFittest().solve());
			System.out.println("Found: " + testPop.getFittest().solveSwitch());
			
			
		} catch (TheException e) {
			System.out.println(e.getMessage());
		}
		
	}
}
